home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / c / RConfig.lha / RConfig_v1.1 / rlib / rlib_stkchk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-13  |  4.8 KB  |  169 lines

  1. /*
  2.  * rlib.c   v1.3
  3.  * ~~~~~~
  4.  *   Copyright (C) 1986,1987 by Manx Software Systems, Inc.
  5.  *   Copyright (C) 1992 by Anthon Pang, Omni Communications Products.
  6.  *
  7.  *   Replacement library for:
  8.  *     - stkchk.a68
  9.  */
  10.  
  11. /*
  12.  * stkchk()
  13.  */
  14. #ifdef __STKCHK_REPLACE
  15.  
  16. #if defined(__BETTER_STKCHK) && defined(__DYNASTACK_STKCHK)
  17. #error "Conflicting stkchk() flags--{BETTER, DYNASTACK}"
  18. #endif
  19.  
  20. #if defined(__BETTER_STKCHK) && defined(__DYNASTACK_STKCHK)
  21. #error "Missing stkchk() flags--{BETTER, DYNASTACK}"
  22. #endif
  23.  
  24. #asm
  25.     cseg
  26.  
  27.     public  __stkbase
  28.     public  __stkover
  29.     public  _malloc
  30.     public  __savsp
  31.  
  32. ; constants defined externally...examples
  33. ;   STKCHK_MIN_STACK    SET 2768
  34. ;   STKCHK_STACK_SIZE   SET 8192
  35. ;   STKCHK_CONTEXT_SIZE SET  128
  36.  
  37. ; __stkchk
  38. ;
  39. ;   - check if stack's magic cookie munged
  40. ;   - check if sufficent stack for stack frame
  41. ;   - allocate additional stack space if required (and enabled)
  42. ; scratch registers: d0/a0-a1
  43.  
  44.     public  __stkchk
  45. __stkchk:
  46.     move.l  __stkbase,a0
  47.  
  48.     cmp.l   #'MANX',(a0)                ; check magic cookie
  49.     bne.s   crunch                      ; branch if stack munged
  50.  
  51.     add.w   #%%STKCHK_MIN_STACK,a0      ; check stack space available
  52.     neg.w   d0
  53.     add.w   d0,a0
  54.     cmp.l   a7,a0
  55.  
  56. #endasm
  57.  
  58. #ifdef __BETTER_STKCHK
  59. #asm
  60.     bge.s   crunch                      ; branch if stack would overflow
  61. #endasm
  62. #endif
  63.  
  64. #ifdef __DYNASTACK_STKCHK
  65. #asm
  66.     blt.s   captain                     ; branch if there's enough stack
  67.  
  68.     ext.l   d0                          ; alloc mem for size of stack frame...
  69.     add.l   #%%STKCHK_STACK_SIZE,d0     ; ...and add a bit for future use
  70.     move.l  d0,-(a7)
  71.     jsr     _malloc#
  72.  
  73.     tst.l   d0                          ; check ptr
  74.     beq.s   crunch                      ; branch if unable to alloc memory
  75.  
  76.     move.l  d0,a0                       ; d0 = a0 = new stkbase
  77.     move.l  #'MANX',(a0)                ; store magic cookie
  78.     move.l  (a7)+,a0                    ; pop size
  79.     add.l   d0,a0                       ; get top of new stack
  80.  
  81.     move.l  __stkbase,-(a0)             ; save old stkbase on extension stack
  82.     move.l  a7,-(a0)                    ; save the current stack pointer
  83.     move.l  d0,__stkbase                ; store new stkbase
  84.  
  85.     move.l  __savsp,a1                  ; get top
  86.     cmp.l   a1,a7
  87.     bge.s   copyfullcontext             ; ignore the case where the extension
  88.                                         ; stack is higher than the orig. stack
  89.  
  90.                                         ; at this point: a1 > a7
  91.     sub.l   a7,a1                       ; get difference of top & current sp
  92.                                         ; this represents amt of valid context
  93.                                         ; plus 8
  94.  
  95.     cmp.l   #%%STKCHK_CONTEXT_SIZE+8,a1 ; compare difference with context size
  96.     bge.s   copyfullcontext             ; if a1 greater, a full context is
  97.                                         ; available
  98.  
  99. copypartialcontext:     ; but pad it out to 128 bytes
  100.     sub.l   #%%STKCHK_CONTEXT_SIZE,a0
  101.     add.l   a1,a0                       ; skip unavailable context
  102.  
  103.     move.l  a1,d0                       ; number of bytes to copy
  104.                                         ; (this may not work out to
  105.                                         ; an even number of longs)
  106.  
  107.     lea     8(a7,d0),a1
  108.  
  109.     lsr.l   #1,d0                       ; number of words to copy
  110.     subq.l  #1,d0                       ; number of words to copy - 1
  111.  
  112.     bra.s   copynextword
  113.  
  114. copyfullcontext:
  115.     moveq   #(%%STKCHK_CONTEXT_SIZE-2)/2,d0 ; copy 'small' context from current...
  116.     lea     %%STKCHK_CONTEXT_SIZE+8(a7),a1  ; ...stack to extension stack
  117.  
  118. copynextword:
  119.     move.w  -(a1),-(a0)
  120.     dbra    d0,copynextword
  121.  
  122. finishedcopy:
  123.     move.l  (a7),d0                     ; get return address (caller of stkchk)
  124.  
  125.     move.l  a0,a7                       ; swap stacks
  126.  
  127.     pea     __stkfree#                  ; this is the clean up routine; called
  128.                                         ; when the calling 'proc' ends
  129.  
  130.     move.l  d0,-(a7)                    ; push addr of where to resume
  131. #endasm
  132. #endif
  133.  
  134. #asm
  135. captain:
  136.     rts
  137.  
  138. crunch:
  139.     jmp     __stkover#
  140. #endasm
  141.  
  142. #ifdef __DYNASTACK_STKCHK
  143. #asm
  144.     public  __stkfree
  145.     public  _free
  146.  
  147. ;
  148. ; __stkfree - free a dynamically allocated stack (as stack unwinds)
  149. ;   scratch registers: a0
  150. ;
  151. __stkfree:
  152.     lea     %%STKCHK_CONTEXT_SIZE(a7),a7    ; skip past context (note: no copyback)
  153.  
  154.     move.l  __stkbase,a0                ; temp = current stkbase
  155.     move.l  4(a7),__stkbase             ; restore old stkbase
  156.  
  157.     move.l  (a7),a7                     ; unwind stack
  158.  
  159.     move.l  a0,-(a7)
  160.     jsr     _free                       ; free empty stack
  161.     addq.l  #8,a7                       ; clean up stack after malloc() & free()
  162.  
  163.     rts
  164.  
  165. #endasm
  166. #endif
  167. #endif /* __STKCHK_REPLACE */
  168.